Skip to content
On this page

일본어 폰트·타이포그래피 - 한국인 웹 개발자가 자주 놓치는 것들

  • 일본인 신규 입사자가 일본어 페이지 보고 피드백 줌
    • "쉼표나 장음부호 앞뒤 공백이 이상하다"
    • 企画、制作 에서 오른쪽이 비어 보여서 스페이스 문자 낀 줄 알았음
    • DOM 까보니 스페이스 없음
  • 한글 서비스만 만들 땐 마주칠 일 없던 문제라 정리해둠

、와 ー는 각각 별도의 유니코드 문자

  • = U+3001 IDEOGRAPHIC COMMA
  • = U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK
    • 둘 다 ASCII ,, -와 다른 문자
    • 폰트 안에서 별도 glyph·metrics 가짐
  • 전각 문장부호는 glyph 자체에 내부 여백(side bearing/advance) 있음
    • 눈으로 봤을 때 공백처럼 보여도 실제 스페이스 문자 있는 건 아님

한국어 서비스 습관을 일본어에 그대로 가져가면 어긋나는 지점:

  • 단어 사이에 공백이 있다는 전제
    • → 일본어는 일반 문장에 띄어쓰기가 거의 없음
    • → 줄바꿈 기회가 문자 사이에 존재
  • word-break: keep-all을 자주 씀
    • → 일본어 본문에 적용하면 정상적인 CJK 줄바꿈을 막아서 overflow 생김
  • 쉼표 , 기준으로 생각
    • 는 전각 문장부호라 글리프 폭·여백 모델이 다름
  • 하이픈/대시와 비슷한 선으로 인식
    • 는 가타카나·히라가나 장음부호로 완전히 다른 문자

용어 정리 (한국어 이름으로 기억하고, 괄호 안 한자·발음은 검색 키워드로):

  • 문장부호·기호류 (約物, やくもの, yakumono)
    • 일본어 조판에서 별도 간격 규칙이 붙는 문장부호·기호류
  • 조판 규칙 (文字組み, もじぐみ)
    • 글자 배치·간격·줄바꿈을 아우르는 조판 규칙 전반
  • 금칙 처리 (禁則処理, きんそくしょり, kinsoku shori)
    • 문장부호가 줄 맨 앞/뒤에 부자연스럽게 오는 걸 막는 규칙
  • 전각/반각 (全角/半角)
    • A처럼 폭이 다른 문자 형태
    • 검색·정규화·UI 폭 계산에 영향

lang="ja"

  • 페이지가 일본어면 문서 루트에 lang="ja"
  • 일부 영역만 일본어면 해당 영역에 지정
  • 접근성·음성합성뿐 아니라 :lang(ja) 셀렉터로 일본어 전용 스타일 스코프하는 기준이 됨
<html lang="ja">
...
</html>
<!-- 다국어 페이지 일부만 일본어 -->
<p>
한국어 설명
<span lang="ja">ショート動画広告の企画、制作</span>
</p>
  • 후리가나 필요하면 이미지나 JS로 만들지 말고 <ruby> 태그 사용
<ruby lang="ja">
日本語<rt>にほんご</rt>
</ruby>
  • locale이 일본어인데 루트 lang이 계속 ko로 남아있는 경우 실무에서 은근히 있음
    • 이것부터 먼저 고칠 것

font-family에 적었다고 그 폰트가 그렸다는 뜻은 아님

:lang(ja) {
font-family:
"Hiragino Sans",
"Yu Gothic",
"YuGothic",
"Meiryo",
"Noto Sans JP",
sans-serif;
}
  • 가장 중요한 확인 포인트는 glyph fallback
    • 지정한 폰트가 일본어 글리프를 포함 안 하거나 웹폰트 subset에서 빠지면, 브라우저가 그 문자만 다른 폰트로 대체함
    • , , 괄호 같은 기호만 다른 metrics 가진 폰트로 떨어지면 그 부분만 이질감 생김
    • Chrome DevTools → Elements → Computed → Rendered Fonts 에서 문제되는 노드 직접 확인하는 게 제일 빠름
  • 웹폰트 subset 만들 때 흔한 실수
    • 가나·한자만 남기고 문장부호를 빠뜨림
    • → punctuation만 system fallback으로 튀어서 폰트 안 맞아 보임
  • 폰트 로딩 타이밍도 줄바꿈에 영향
    • 일본어는 문자 단위 줄바꿈이 많아서 fallback font와 최종 font의 advance width 차이가 한 줄의 마지막 문자 위치를 바꿀 수 있음
    • font-display: swap 쓴다면 CLS뿐 아니라 "첫 렌더와 로딩 후 줄바꿈이 달라지는가"도 볼 것

word-break: keep-all을 일본어에 그대로 쓰면 안 됨

  • 일본어는 공백 없이 문장이 이어져서 브라우저가 문자 사이의 줄바꿈 기회를 판단
  • 여기에 금칙처리 규칙까지 겹침
    • 、。)]」』 같은 닫는 문장부호가 줄 맨 앞에 오는 것 피함
    • ([「『 같은 여는 문장부호가 줄 맨 끝에 오는 것 피함
:lang(ja) {
line-break: strict;
word-break: normal;
overflow-wrap: break-word; /* 긴 URL/식별자 같은 예외 대응 */
}
  • 한국어 CSS 복사하면서 가장 자주 하는 실수 — word-break: keep-all을 일본어에도 같이 적용
    • 일본어의 정상적인 CJK 줄바꿈 기회를 지나치게 없애버려서 컨테이너 폭 넘어가는 문제 생김

같은 문장을 폭 260px 박스에 넣고 비교하면 차이가 바로 보임.

word-break: normal
ショート動画広告の企画、制作という講座では、企画から編集まで一連の流れを学びます。
word-break: keep-all
ショート動画広告の企画、制作という講座では、企画から編集まで一連の流れを学びます。
  • keep-all 쪽은 문자 사이의 정상적인 줄바꿈 기회가 막혀서 박스 폭을 넘어가거나 한 단어처럼 취급된 구간이 삐져나옴

font-feature-settings: "palt"

  • OpenType feature는 폰트가 제공하는 대체 glyph·metrics를 선택하는 기능
  • 일본어에서 자주 마주치는 태그
    • palt (비례폭)
    • pwid
    • vert (세로쓰기용)
/* low-level: 폰트가 palt를 제공할 때만 효과가 있음 */
.jp-heading {
font-feature-settings: "palt" 1;
}
/* 가능하면 의미가 더 분명한 상위 속성을 우선 검토 */
.jp-ui {
font-variant-east-asian: proportional-width;
}
  • palt를 "일본어면 무조건 켜야 하는 옵션"으로 다루면 안 됨
    • 폰트와 디자인 의도에 따라 결과 달라짐
    • 이미 letter-spacing으로 자간 조정한 UI에 같이 걸면 、。 같은 문장부호 간격이 예상과 다르게 보일 수 있음
    • 이 효과는 폰트가 palt 테이블을 가지고 있을 때만 나타남
      • 시스템 폰트로 비교하면 브라우저가 palt 지원 안 하는 폰트로 fallback돼서 차이가 거의 안 보일 수 있음
      • 아래 예시는 palt 확실히 지원하는 Noto Sans JP를 웹폰트로 강제 지정해서 비교
palt 없음 (Noto Sans JP)
ショート動画広告の企画、制作という講座では、
font-feature-settings: "palt" 1 (Noto Sans JP)
ショート動画広告の企画、制作という講座では、
  • 같은 폰트인데도 같은 전각 문장부호 주변 여백이 오른쪽에서 눈에 띄게 좁아짐
  • 반대로 시스템 폰트에 그대로 palt만 걸면 폰트가 그 테이블을 갖고 있는지에 따라 결과 달라짐
    • 실제 서비스 적용 전 반드시 실 사용 폰트로 확인할 것
  • 디자인 툴과 브라우저 렌더링이 다르게 보이면 비교 순서
    1. Figma 등에서 어떤 OpenType feature가 활성화됐는지
    2. 브라우저에서 동일 폰트 파일을 쓰는지
    3. font-feature-settings, font-variant-east-asian, letter-spacing 설정이 같은지

text-autospace / text-spacing-trim

  • text-autospace
    • CJK 문자와 Latin/숫자 사이의 자동 간격 제어 (2025 Baseline)
    • "일본어 + 영문 제품명 + 숫자"가 섞이는 UI에서 유용
    • 단, 이미 번역 문자열에 수동으로 공백을 넣어놨다면 중복 간격 생길 수 있음
@supports (text-autospace: normal) {
:lang(ja) {
text-autospace: normal;
}
}
  • text-spacing-trim
    • CJK 문장부호가 가진 내부 여백을 인접 문자나 행 시작/끝에서 다듬는 속성
    • "구두점 주변이 유난히 비어 보인다"는 CS와 개념적으로 가장 가까운 속성
    • 2026년 기준으로도 일부 주요 브라우저에서 지원 제한적
    • polyfill 있다고 가정하지 말고 progressive enhancement로만 쓸 것
@supports (text-spacing-trim: normal) {
:lang(ja) {
text-spacing-trim: normal;
}
}

Intl.Segmenter

  • 일본어 문자열을 split(' ')length로 다루면 안 됨
    • 공백으로 단어가 구분되지 않기 때문
    • 단어 수·검색 하이라이트·텍스트 분석은 locale-aware segmentation 사용
const segmenter = new Intl.Segmenter('ja-JP', {
granularity: 'word',
});
const segments = [...segmenter.segment('吾輩は猫である。名前はたぬき。')];
const words = segments
.filter(({ isWordLike }) => isWordLike)
.map(({ segment }) => segment);
  • "문자 수"와 UTF-16 길이도 다름
    • 평범한 일본어 BMP 문자는 text.length와 겉보기 글자 수가 우연히 맞아떨어지는 경우 많음
    • 이모지·결합 문자·variation selector 섞이면 어긋남
    • 사용자가 눈으로 보는 글자 수 세야 한다면 grapheme 기준으로 셀 것
const graphemes = new Intl.Segmenter('ja-JP', {
granularity: 'grapheme',
});
const count = [...graphemes.segment(text)].length;
  • 정규화도 표시 문자열과 검색 키를 분리해야 함
    • NFKC는 전각 Latin/숫자, 반각 가타카나 같은 compatibility 형태를 접어서 검색 편의성 높임
    • 단, 원문 표기 자체를 바꿔버림
    • 저장·표시용 원문은 그대로 두고, 검색용 파생 키에만 적용하는 편이 안전
const raw = input; // 표시/원본 보존
const searchKey = raw.normalize('NFKC').toLocaleLowerCase('ja-JP');
  • CSS로 풀 문제를 문자열에 공백 하드코딩해서 고치면 안 됨
    • 企画、制作企画、 制作처럼 번역 문자열에 스페이스 박아넣는 방식
    • 폰트가 바뀌거나 text-autospace가 활성화되는 순간 다시 깨짐
    • 복사·검색 데이터에도 영향 줌

"일본어 공백이 이상하다" CS가 오면 이 순서로 봄

  1. 문자 확인
    • 실제로 (U+30FC), (U+3001)인지
    • ASCII 유사문자로 변환되지 않았는지
  2. DOM whitespace 확인
    • 문자열에 실제 space/NBSP가 삽입됐는지
  3. Rendered Fonts 확인
    • 문제되는 punctuation만 fallback된 것은 아닌지
  4. CSS 제거 실험
    • letter-spacing, word-spacing, font-feature-settings를 하나씩 꺼봄
  5. 일본어 전용 폰트 강제
    • Noto Sans JP 등 확실한 일본어 폰트로 비교
  6. 줄바꿈 규칙 확인
    • lang="ja", line-break, word-break
  7. 브라우저/OS 비교
    • macOS Hiragino, Windows Yu Gothic/Meiryo 등 fallback 차이 분리
  8. 디자인 툴 비교
    • 동일 폰트 파일·weight·OpenType feature가 맞는지
  • , 전후의 "공백 균형"은 실제 스페이스보다 glyph metrics + fallback + letter-spacing + OpenType 조합일 가능성을 먼저 의심하는 게 맞음

참고

Edit this page
최근 수정 시각 9/6/2026